package com.ctgu.tengyun.controller.user;

import com.ctgu.tengyun.bean.convert.UserConvert;
import com.ctgu.tengyun.bean.errorcode.UserErrorCode;
import com.ctgu.tengyun.bean.request.ResetUserPasswordRequest;
import com.ctgu.tengyun.bean.request.SimpleLongRequest;
import com.ctgu.tengyun.bean.request.SysUserBaseInfo;
import com.ctgu.tengyun.bean.response.UserListResponse;
import com.ctgu.tengyun.domain.SysRole;
import com.ctgu.tengyun.domain.SysUser;
import com.ctgu.tengyun.exception.ErrorCodeException;
import com.ctgu.tengyun.manager.PermissionManager;
import com.ctgu.tengyun.manager.UserRoleScheduleManager;
import com.ctgu.tengyun.service.role.SysRoleService;
import com.ctgu.tengyun.service.user.SysUserService;
import com.ctgu.tengyun.util.MD5Utils;
import com.ctgu.tengyun.util.ParameterTool;
import com.ctgu.tengyun.util.StringUtils;
import com.ctgu.tengyun.util.Validator;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;

/**
 * Created by liaoweizhi on 2019/7/17.
 */
@RestController
@RequestMapping(value = "/v1/user/")
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private PermissionManager permissionManager;

    @PostMapping(value = "save")
    public Object saveOrUpdate(@RequestBody SysUser request) {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.addUrlPatterns();
        Validator.assertHasFields(!StringUtils.isEmpty(request.getUserName()), "user name is required.");
        Validator.assertHasFields(!StringUtils.isEmpty(request.getPassword()), "password is required.");
        Validator.assertHasFields(null != request.getRoleId(), "roleId is required.");

        String userName = request.getUserName().trim();
        String password = request.getPassword().trim();

        if (password.length() < 6) {
            throw new ErrorCodeException(UserErrorCode.password_too_short, UserErrorCode.password_too_short.getMsg());
        }

        SysRole sysRole = sysRoleService.selectByPrimaryKey(request.getRoleId());
        Validator.assertResourceFound(null != sysRole, "roleId is invalid");

        try {
            request.setUserName(userName);
            request.setPassword(MD5Utils.MD5EncodeUTF8(password));
            sysUserService.insertSelective(request);
        } catch (DuplicateKeyException e) {
            throw new ErrorCodeException(UserErrorCode.username_is_exist, UserErrorCode.username_is_exist.getMsg());
        }

        return ImmutableMap.of("id", request.getId());
    }

    @PostMapping(value = "update_base_info")
    public Object update(@RequestBody SysUserBaseInfo request) {
        Validator.assertHasFields(null != request.getId(), "userId is required.");
        SysUser sysUser = sysUserService.selectByPrimaryKey(request.getId());
        Validator.assertResourceFound(null != sysUser, "user not found, userId:" + request.getId());

        if (null != request.getRoleId()) {
            SysRole sysRole = sysRoleService.selectByPrimaryKey(request.getRoleId());
            Validator.assertResourceFound(null != sysRole, "roleId is invalid");
        }

        sysUserService.updateBaseInfo(request);

        return ImmutableMap.of("id", request.getId());
    }

    @PostMapping(value = "reset_password")
    public Object resetPassword(@RequestBody ResetUserPasswordRequest request) {
        String userName = request.getUserName().trim();
        String oldPassword = request.getOldPassword().trim();
        String newPassword = request.getNewPassword().trim();

        Validator.assertHasFields(!StringUtils.isEmpty(userName), "user name is required.");
        Validator.assertHasFields(!StringUtils.isEmpty(oldPassword), "old password is required.");
        Validator.assertHasFields(!StringUtils.isEmpty(newPassword), "new password is required.");

        SysUser sysUser = sysUserService.selectByUserName(request.getUserName());
        Validator.assertResourceFound(null != sysUser, "user not found, userName:" + request.getUserName());

        String md5OldPassword = MD5Utils.MD5EncodeUTF8(oldPassword);
        String md5NewPassword = MD5Utils.MD5EncodeUTF8(newPassword);
        if (!sysUser.getPassword().equals(md5OldPassword)) {
            throw new ErrorCodeException(UserErrorCode.old_password_invalid, UserErrorCode.old_password_invalid.getMsg());
        }

        sysUserService.updatePassword(userName, md5OldPassword, md5NewPassword);

        return ImmutableMap.of("id", sysUser.getId());
    }

    @RequestMapping(value = "list")
    public UserListResponse list(HttpServletRequest request) {
        Integer pageNo = ParameterTool.getParameterInteger(request, "pageNo", 1);
        Integer pageSize = ParameterTool.getParameterInteger(request, "pageSize", 10);
        String userName = ParameterTool.getParameterString(request, "name", null);
        String contactNo = ParameterTool.getParameterString(request, "contactNo", null);

        Validator.validateGt(pageNo, 0);
        Validator.validateBetweenIn(pageSize, 0, 1000);

        SysUser queryUser = new SysUser();
        queryUser.setUserName(userName);
        queryUser.setContactNo(contactNo);
        Integer totalCount = sysUserService.countByExample(queryUser);
        List<SysUser> sysUserList = Collections.emptyList();
        if (totalCount > 0) {
            sysUserList = sysUserService.selectByExample(queryUser, pageNo, pageSize);
        }

        return UserConvert.toUserListResponse(totalCount, pageSize, sysUserList);
    }

    @GetMapping(value = "detail/{id}")
    public SysUserBaseInfo detail(@PathVariable("id") Long userId) {
        SysUser sysUser = sysUserService.selectByPrimaryKey(userId);
        Validator.assertResourceFound(null != sysUser, "user not found, userId:" + userId);

        SysRole sysRole = UserRoleScheduleManager.getRoleById(sysUser.getRoleId());
        sysUser.setRoleName(null != sysRole ? sysRole.getName() : "");

        SysUserBaseInfo baseInfo = new SysUserBaseInfo();
        BeanUtils.copyProperties(sysUser, baseInfo);

        return baseInfo;
    }

    @PostMapping(value = "delete")
    public Object delete(@RequestBody SimpleLongRequest request) {
        Validator.assertHasFields(null != request.getData(), "data is required.");
        Long userId = request.getData();

        SysUser sysUser = sysUserService.selectByPrimaryKey(userId);
        Validator.assertResourceFound(null != sysUser, "user not found, userId:" + userId);

        sysUserService.deleteUserById(userId);

        return ImmutableMap.of("id", sysUser.getId());
    }

}
